package org.zqh.ncc.thread;

import com.alibaba.fastjson.JSON;
import nccloud.open.api.auto.token.cur.utils.APICurUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.stereotype.Component;
import org.zqh.ncc.config.CgToErp;
import org.zqh.ncc.config.NcConfig;
import org.zqh.ncc.ncmodel.CG.Po_arriveorder;
import org.zqh.ncc.ncmodel.CG.Po_arriveorder_b;
import org.zqh.ncc.ncmodel.NcBillReturn;
import org.zqh.ncc.utils.TimeUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.PriorityBlockingQueue;

/**
 * 定时扫描t_bangdan表，发现有需要推NC单据的记录，就进行处理,该线程只处理磅单推送NC到货单
 */
@Component
public class CgToErpThread extends CommonThread<CgToErp> {
    volatile long beginTime = 0;
    NcConfig ncConfig;
    APICurUtils apiUtils;
    String token;

    /**
     *
     */
    public CgToErpThread(PriorityBlockingQueue<CgToErp> CgToErpQueue, @Qualifier("cgApiCurUtils") APICurUtils apiCurUtils, NcConfig ncConfig) {
        super(CgToErpQueue);
        this.apiUtils = apiCurUtils;
        this.ncConfig = ncConfig;
        apiUtils.init(ncConfig.getDx_cg_ip(), ncConfig.getDx_cg_port(), ncConfig.getDx_biz_center(), ncConfig.getDx_client_id(), ncConfig.getDx_client_secret(), ncConfig.getDx_pubKey(), ncConfig.getDx_user_name(), ncConfig.getDx_pwd());
        this.setName("cgToErpThread");


    }

    /**
     * 线程启动运行，推送状态报告
     */
    public void run() {
        while (!isStopping) {
            try {
                List<CgToErp> bdList = getCgToErpList(10);
                if (bdList.size() > 0) {
                    processList(bdList);
                    beginSleep(100);
                } else {
                    beginSleep(3000);
                }
            } catch (Exception e) {
                log.error("", e);
                beginSleep(10000);
            }
        }
        isStopped = true;
    }

    /**
     * @param bdList
     */
    private void processList(List<CgToErp> bdList) {
        beginTime = System.currentTimeMillis();
        for (CgToErp cgToErp : bdList) {
            log.debug("before CgToErp post :" + cgToErp);
            try {
                token = apiUtils.getToken();
                apiUtils.setApiUrl(ncConfig.getDx_url());
                String sendJson = toErp(cgToErp);
                log.info("send: " + ncConfig.getDx_cg_ip() + ":" + ncConfig.getDx_cg_port() + " json=" + sendJson);
                String apiRetrun = apiUtils.getAPIRetrun(token, sendJson);
                log.info((System.currentTimeMillis() - beginTime) + " ms return: " + apiRetrun);
                NcBillReturn ncBillReturn = JSON.parseObject(apiRetrun, NcBillReturn.class);
                if (null != ncBillReturn) {
                    if (null == ncBillReturn.getMessage())
                        ncBillReturn.setMessage("null");
                    else if (ncBillReturn.getMessage().length() > 300) {
                        ncBillReturn.setMessage(ncBillReturn.getMessage().replaceAll("'", "#"));
                        ncBillReturn.setMessage(ncBillReturn.getMessage().substring(ncBillReturn.getMessage().length() - 298));
                    }
                    String sql = "update t_bangdan set resulttime=sysdate,resultmemo='" + ncBillReturn.getMessage() + "',resulttoerp='" + (ncBillReturn.isSuccess() ? "1" : "-1") +
                            "' where vbdcode='" + cgToErp.getVbdcode() + "'";
                    try {
                        jdbcTemplate.update(sql);
                    } catch (Exception sqlError) {
                        log.error("sql=" + sql, sqlError);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.error("调用接口错误：", e);
            }
        }
    }

    /**
     * 先更新t_bangdan表，加上一个uuid,后面根据这个uuid进行select，更新那些需要同步推送到NC的过磅单，根据resulttoerp字段的值
     *
     * @param count 每次处理的数量
     * @return
     */
    private List<CgToErp> getCgToErpList(int count) {
        List<CgToErp> bdList = new ArrayList<>();
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        int rowCount = 0;
        String sql = "update t_bangdan set resulttoerp='2',updateuuid='" + uuid + "',duuidtime=sysdate where vbdtype='CG' and resulttoerp='0' and vdelflag='0' and rownum <= " + count;
        try {
            rowCount = jdbcTemplate.update(sql);
        } catch (Exception sqlError) {
            log.error("sql=" + sql, sqlError);
        }
        if (rowCount > 0) {
            bdList = jdbcTemplate.query("select * from v_cg_bangdan where updateuuid='" + uuid + "'", new BeanPropertyRowMapper(CgToErp.class));
            if (bdList.size() != rowCount) {
                log.warn("uuid=" + uuid + " updateCount=" + rowCount + " getCount=" + bdList.size() + ", 注意检查");
            }
        }
        return bdList;
    }

    /**
     * 从视图返回的对象，转换为json，传递给NC接口，推式生成到货单
     *
     * @param cgToErp
     * @return
     */
    private String toErp(CgToErp cgToErp) {
        org.zqh.ncc.ncmodel.CG.JsonRootBean jb = new org.zqh.ncc.ncmodel.CG.JsonRootBean();
        org.zqh.ncc.ncmodel.CG.BillInfo billInfo = new org.zqh.ncc.ncmodel.CG.BillInfo();

        Po_arriveorder po_arriveorder = new Po_arriveorder();
        po_arriveorder.setPk_org(cgToErp.getPk_org());
        po_arriveorder.setVtrantypecode(cgToErp.getVtrantypecode());
        //2024-04-30 增加Derpbilldate，如果为空，则erp制单时间为地磅第二次过磅时间，否则为derpbilldate的时间
        if (null == cgToErp.getDerpbilldate())
            po_arriveorder.setDbilldate(TimeUtil.getStrDateFormat(cgToErp.getDouttime()));
        else
            po_arriveorder.setDbilldate(TimeUtil.getStrDateFormat(cgToErp.getDerpbilldate()));
        po_arriveorder.setPk_dept(cgToErp.getPk_dept());
        po_arriveorder.setPk_supplier(cgToErp.getVtocode());

        if (null != cgToErp.getVpackage() && cgToErp.getVpackage().equalsIgnoreCase("采购退货"))
            po_arriveorder.setBreturn("Y");
        else
            po_arriveorder.setBreturn("N");

        billInfo.setPo_arriveorder(po_arriveorder);
        //2024-02-21 王沐奇新需求，一次过磅，可以选择采购订单多行，生成对应多行的到货单
        String[] hids = cgToErp.getVerphid().split(",");
        String[] bids = cgToErp.getVerpbid().split(",");
        String[] oldNums = new String[bids.length];
        //修复部分老的过磅单erpbnum为空的bug
        if (cgToErp.getVerpbnum() == null) {
            oldNums[0] = "" + cgToErp.getNyuanfj();
        } else {
            oldNums = cgToErp.getVerpbnum().split(",");
        }
        List<Po_arriveorder_b> blist = new ArrayList<>();
        //2024-05-08 解决净重减去扣重后出现的浮点数小数位问题
        float njk = Math.round((cgToErp.getNjingzhong() - cgToErp.getNkouzhong()) * 1000) / 1000f;
        Float[] newNums = getNewNum(bids.length, oldNums, njk);
        int i = 0;
        for (String bid : bids) {
            Po_arriveorder_b po_arriveorder_b = new Po_arriveorder_b();
            po_arriveorder_b.setPk_material(cgToErp.getVmatcode());
            //2022-12-22 订单自定义项目24，确定到货结算按原发数结算
            if (cgToErp.getNyuanfj() > 0) {
                po_arriveorder_b.setNnum(Float.parseFloat(oldNums[i]));
                po_arriveorder_b.setNastnum(Float.parseFloat(oldNums[i]));
                po_arriveorder_b.setNplannum(Float.parseFloat(oldNums[i]));
                po_arriveorder_b.setNplanastnum(Float.parseFloat(oldNums[i]));
            } else {
                //2024-07-31修改逻辑，如果分配的数量为0，则这一行不用传NC
                if (newNums[i] == 0)
                    continue;
                po_arriveorder_b.setNnum(newNums[i]);
                po_arriveorder_b.setNastnum(newNums[i]);
                po_arriveorder_b.setNplannum(newNums[i]);
                po_arriveorder_b.setNplanastnum(newNums[i]);
            }
            po_arriveorder_b.setNorigtaxprice(cgToErp.getNorigtaxprice());
            po_arriveorder_b.setNorigprice(cgToErp.getNorigprice());
            po_arriveorder_b.setCtaxcodeid(cgToErp.getCtaxcodeid());
            po_arriveorder_b.setCorigcurrencyid(cgToErp.getCorigcurrencyid());
            po_arriveorder_b.setVbdef14("" + cgToErp.getNpizhong());
            po_arriveorder_b.setVbdef15(TimeUtil.getStrDateFormat(cgToErp.getDouttime()));
            po_arriveorder_b.setVbdef16("" + cgToErp.getNmaozhong());
            po_arriveorder_b.setVbdef17(TimeUtil.getStrDateFormat(cgToErp.getDintime()));
            //2024-04-16修改，龙光单独处理，如果有扣重，则传给ERP的净重是扣除扣重之后的，其他地磅的净重是已经减过扣重的了
            po_arriveorder_b.setVbdef18("" + njk);
            po_arriveorder_b.setVbdef19(cgToErp.getVcarno());
            po_arriveorder_b.setVbdef20(cgToErp.getVbdcode());
            po_arriveorder_b.setCsourceid(hids[i]);
            po_arriveorder_b.setCsourcebid(bids[i]);

            blist.add(po_arriveorder_b);
            i++;
        }
        billInfo.setPo_arriveorder_b(blist);
        List<org.zqh.ncc.ncmodel.CG.BillInfo> billInfoList = new ArrayList<>();
        billInfoList.add(billInfo);
        jb.setBillInfo(billInfoList);

        return JSON.toJSONString(jb);
    }

    private Float[] getNewNum(int bidsLen, String[] oldNums, float jinzhong) {
        Float[] newNums = new Float[oldNums.length];

        if (bidsLen == 1) {
            newNums[0] = (Float) jinzhong;
        } else {

            int i = 0;
            for (String bnum : oldNums) {
                float curNum = 0;
                if (null == bnum)
                    curNum = 0;
                else
                    curNum = Float.parseFloat(bnum);
                float totalNum = 0;
                for (int j = 0; j < newNums.length; j++) {
                    if (null != newNums[j])
                        totalNum += newNums[j];
                }

                if (curNum > 0 && (totalNum + curNum) <= jinzhong) {
                    newNums[i] = (Float) curNum;
                } else {
                    newNums[i] = (Float) (Math.round((jinzhong - totalNum) * 1000) / 1000f);
                    if (newNums[i] <= 0)
                        newNums[i] = (Float) 0F;
                }
                i++;
            }
        }
        return newNums;

    }

}
